#include <string.h>
#include <stdio.h>
#include <string>
#include <stdexcept>

#define LOG4X_C
#ifdef LOG4X_C
#include "log4x-c.h"
#else
#include "log4x.h"
using namespace log4x;
#endif

#include "thread.h"
using namespace std;

bool exit_ = false;

char A[] = "abc def abc def adc";
const char *pool = 
 "    PID NAME                    STATUS        INACTIVE\n"  
 "    ad4 TP_ThreadPool                2              50\n"
 "   1f18 TP_Mempool                   2              27\n"
 "   2230 TP_Logger-MSV                2             769\n"
 "    7ac TP_Pu::login-MSV             2              26\n"
 "   25c4 TP_Pu::login-MSV             2              26\n"
 "   1ef8 TP_Sevent-Priv-MSV           2               9\n"
 "    50c TP_Sevent-MSV                2               9\n"
 "   1a50 TP_Sevent-Link-MSV           2               9\n"
 "   17fc TP_ServMgr::ui-MSV           2               9\n"
 "   1618 TP_ServMgr::timer-MSV        2              23\n"
 "   1a20 TP_REConverter-MSV           2              27\n";

class MyThread : public log4x::Thread
{
public:
    MyThread(const char * key, int index)
    {
        this->key   = key;
        this->index = index;
    }
    virtual ~MyThread() { }

protected:
    virtual void run()
    {
        while (!exit_)
        {
#if 0
            switch (index)
            {
            case 0:
                LOGF_TRACE(key.c_str(), "thread: %d", index);
                break;
            case 1:
                LOGF_DEBUG(key.c_str(), "thread: %d", index);
                break;
            case 2:
                LOGF_INFO(key.c_str(), "thread: %d", index);
                break;
            case 3:
                LOGF_WARN(key.c_str(), "thread: %d", index);
                break;
            case 4:
                LOGF_ERROR(key.c_str(), "thread: %d", index);
                break;
            case 5:
                LOGF_FATAL(key.c_str(), "thread: %d", index);
                break;
            default:
                break;
            }
#endif
            if (index == 5)
            {
                LOGF_ERROR("tpool", "\n%s", pool);
            }

            if (index == 6)
            {
                LOGF_FATAL("large", "%s", A);
            }

            LOGF_TRACE("test1", "thread: %d", index);
            LOGF_DEBUG("test2", "thread: %d", index);
            LOGF_INFO("test3", "thread: %d", index);
            LOGF_WARN("test4", "thread: %d", index);
            LOGF_ERROR("test5", "thread: %d", index);
            LOGF_FATAL("test6", "thread: %d", index);
            LOGF_DEBUG("TEST7", "thread: %d", index);

#if 0
            LOGF_TRACE("test1", "thread: %d", index);
            LOGF_DEBUG("test2", "thread: %d", index);
            LOGF_INFO("test3", "thread: %d", index);
            LOGF_WARN("test4", "thread: %d", index);
            LOGF_ERROR("test5", "thread: %d", index);
            LOGF_FATAL("test6", "thread: %d", index);

            LOGF_TRACE("test1", "thread: %d", index);
            LOGF_DEBUG("test2", "thread: %d", index);
            LOGF_INFO("test3", "thread: %d", index);
            LOGF_WARN("test4", "thread: %d", index);
            LOGF_ERROR("test5", "thread: %d", index);
            LOGF_FATAL("test6", "thread: %d", index);

            LOGF_TRACE("test1", "thread: %d", index);
            LOGF_DEBUG("test2", "thread: %d", index);
            LOGF_INFO("test3", "thread: %d", index);
            LOGF_WARN("test4", "thread: %d", index);
            LOGF_ERROR("test5", "thread: %d", index);
            LOGF_FATAL("test6", "thread: %d", index);

            LOGF_TRACE("test1", "thread: %d", index);
            LOGF_DEBUG("test2", "thread: %d", index);
            LOGF_INFO("test3", "thread: %d", index);
            LOGF_WARN("test4", "thread: %d", index);
            LOGF_ERROR("test5", "thread: %d", index);
            LOGF_FATAL("test6", "thread: %d", index);

            LOGF_TRACE("test1", "thread: %d", index);
            LOGF_DEBUG("test2", "thread: %d", index);
            LOGF_INFO("test3", "thread: %d", index);
            LOGF_WARN("test4", "thread: %d", index);
            LOGF_ERROR("test5", "thread: %d", index);
            LOGF_FATAL("test6", "thread: %d", index);

            LOGF_TRACE("test1", "thread: %d", index);
            LOGF_DEBUG("test2", "thread: %d", index);
            LOGF_INFO("test3", "thread: %d", index);
            LOGF_WARN("test4", "thread: %d", index);
            LOGF_ERROR("test5", "thread: %d", index);
            LOGF_FATAL("test6", "thread: %d", index);

            LOGF_TRACE("test1", "thread: %d", index);
            LOGF_DEBUG("test2", "thread: %d", index);
            LOGF_INFO("test3", "thread: %d", index);
            LOGF_WARN("test4", "thread: %d", index);
            LOGF_ERROR("test5", "thread: %d", index);
            LOGF_FATAL("test6", "thread: %d", index);

            LOGF_TRACE("test1", "thread: %d", index);
            LOGF_DEBUG("test2", "thread: %d", index);
            LOGF_INFO("test3", "thread: %d", index);
            LOGF_WARN("test4", "thread: %d", index);
            LOGF_ERROR("test5", "thread: %d", index);
            LOGF_FATAL("test6", "thread: %d", index);

            LOGF_TRACE("test1", "thread: %d", index);
            LOGF_DEBUG("test2", "thread: %d", index);
            LOGF_INFO("test3", "thread: %d", index);
            LOGF_WARN("test4", "thread: %d", index);
            LOGF_ERROR("test5", "thread: %d", index);
            LOGF_FATAL("test6", "thread: %d", index);

            LOGF_TRACE("test1", "thread: %d", index);
            LOGF_DEBUG("test2", "thread: %d", index);
            LOGF_INFO("test3", "thread: %d", index);
            LOGF_WARN("test4", "thread: %d", index);
            LOGF_ERROR("test5", "thread: %d", index);
            LOGF_FATAL("test6", "thread: %d", index);

            LOGF_TRACE("test1", "thread: %d", index);
            LOGF_DEBUG("test2", "thread: %d", index);
            LOGF_INFO("test3", "thread: %d", index);
            LOGF_WARN("test4", "thread: %d", index);
            LOGF_ERROR("test5", "thread: %d", index);
            LOGF_FATAL("test6", "thread: %d", index);

            LOGF_TRACE("test1", "thread: %d", index);
            LOGF_DEBUG("test2", "thread: %d", index);
            LOGF_INFO("test3", "thread: %d", index);
            LOGF_WARN("test4", "thread: %d", index);
            LOGF_ERROR("test5", "thread: %d", index);
            LOGF_FATAL("test6", "thread: %d", index);
#endif
            sleep(1000);
            /* sys->sleep(10); */
        }
    }
private:
    string key;
    int    index;
};

int main(int argc, char *argv[])
{
    /* memset(A, 'a', sizeof(A)); */
#ifdef LOG4X_C 
    log4x_init();
    /* log4x_setdisplay("test1", false); */
#else
    ilog4x *i = ilog4x::instance();
    i->config("log.ini");

    int result = 0;
    result = i->start();
    result = i->start();

    i->setAutoUpdate(10);
    i->setDisplay("test1", false);
#endif
    LOG4X_DEBUG_LEVEL("test1", LOG_LEVEL_TRACE);
    LOGF_INFO("main", "111111%s", A);

#if 0
    /* THROW_ERROR("main", "%s", "test"); */
    MyThread t0("main", 0);
    MyThread t1("test1", 1);
    MyThread t2("test2", 2);
    MyThread t3("test3", 3);
    MyThread t4("test4", 4);
    MyThread t5("test5", 5);
    MyThread t6("large", 6);

    t0.start();
    t1.start();
    t2.start();
    t3.start();
    t4.start();
    t5.start();
    t6.start();

    /* sys->sleep(2000); */
    /* int a = *(int *)0x123456; */
    /* printf("%s", a); */

    getchar();

    exit_ = true;

    t0.stop();
    t1.stop();
    t2.stop();
    t3.stop();
    t4.stop();
    t5.stop();
    t6.stop();
#endif

#ifdef LOG4X_C
    log4x_uninit();
#else
    i->stop();
#endif

    getchar();
    return 0;
}
